1 /************************************************************
2 * Copyright *
3 * Portions of this software are Copyright (c) 1993 - 2002, *
4 * Chad Z. Hower (Kudzu) and the Indy Pit Crew *
5 * - http://www.nevrona.com/Indy/ *
6 ************************************************************/
7
8 /************************************************************
9 * Copyright *
10 * Portions of this software are Copyright (c) 1993 - 2002, *
11 * Chad Z. Hower (Kudzu) and the Indy Pit Crew *
12 * - http://www.nevrona.com/Indy/ *
13 ************************************************************/
14 package org.indy.io;
15
16 import java.io.BufferedInputStream;
17 import java.io.BufferedOutputStream;
18 import java.io.ByteArrayOutputStream;
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.io.InterruptedIOException;
22
23 import java.net.InetAddress;
24 import java.net.Socket;
25 import java.net.SocketException;
26 import java.net.UnknownHostException;
27
28 import java.util.Map;
29
30 import org.indy.IndyException;
31 import org.indy.Status;
32
33 import org.indy.socks.SocksInfo;
34
35 import org.indy.util.IndyUtilities;
36
37
38 /***
39 * An implementation of {@link IOHandler} that handles IO for sockets.
40 *
41 *@see IOHandler
42 *@see AbstractIOHandler
43 *@author Owen Green
44 */
45 public class IOHandlerSocket extends AbstractIOHandler {
46 /***
47 * Carriage Return
48 */
49 protected static final int CR = 13;
50
51 /***
52 * Line Feed
53 */
54 protected static final int LF = 10;
55 private final ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
56 private MutableBufferedInputStream input;
57 private BufferedOutputStream output;
58 private SocksInfo _info = null;
59 private boolean useNagle = true;
60 private boolean connected = false;
61
62 /***
63 * Instance of <code>java.net.Socket</code> used by this IOHandler.
64 */
65 protected Socket binding = null;
66
67 /***
68 * Constructs a new instance of <code>IOHandlerSocket</code>
69 * around a pre-made <code>java.net.Socket</code>
70 *
71 * @param socket The socket to use with the IOHandler
72 * @throws IndyIOException If an IO error occurs whilst configuring the socket
73 */
74 public IOHandlerSocket(Socket socket) throws IndyIOException {
75 if (socket == null) {
76 /*** @todo resource message */
77 throw new NullPointerException("Socket is null");
78 }
79
80 binding = socket;
81
82 try {
83 binding.setKeepAlive(false);
84
85 input = new MutableBufferedInputStream(binding.getInputStream());
86 output = new BufferedOutputStream(binding.getOutputStream());
87 }
88 catch (IOException ex) {
89 ex.printStackTrace();
90 throw new IndyIOException(ex);
91 }
92
93 connected = true;
94 }
95
96 /***
97 * Constructs a new instance of <code>IOHandlerSocket</code>
98 */
99 public IOHandlerSocket() {
100 }
101
102 /***
103 * Sets the SOCKS configuration to be used with this socket connection.
104 * NOTE: Setting this whilst the socket is connected will have no effect.
105 *
106 *@param info The new socks configuration data to be used.
107 */
108 protected void setSocksInfo(SocksInfo info) {
109 _info = new SocksInfo(info);
110 }
111
112 /***
113 * Sets whether to use Nagle's Algorithm with this socket or not.
114 * The default is <code>true</code>
115 *
116 *@param use <code>true</code> to use Nagle's Algorithm, <code>false</code> otherwise
117 *@throws IndyIOException if the underlying socket throws an exception whilst setting this property
118 *@see java.net.Socket#setTcpNoDelay(boolean)
119 */
120 public void setUseNagle(boolean use) throws IndyIOException {
121 useNagle = use;
122
123 if (isConnected()) {
124 try {
125 binding.setTcpNoDelay(use);
126 }
127 catch (SocketException se) {
128 throw new IndyIOException(se);
129 }
130 }
131 }
132
133 /***
134 * Gets the SOCKS data in use with this <code>IOHandlerSocket</code>
135 *
136 *@return The current SOCKS configuration
137 */
138 protected SocksInfo getSocksInfo() {
139 return new SocksInfo(_info);
140 }
141
142 /***
143 * Returns a string representing the IP address of the peer that
144 * this socket is connected to, or a blank string if the socket
145 * is not connected.
146 *
147 *@return The IP address of the socket's peer, or a blank string if unconnected.
148 */
149 public String getPeerIP() {
150 if (connected) {
151 return binding.getInetAddress().getHostAddress();
152 }
153 else {
154 return "";
155 }
156 }
157
158 /***
159 * Gets the remote port to which this socket is connected, or 0 if unconnected
160 *
161 *@return The remote port.
162 */
163 public int getPeerPort() {
164 if (connected) {
165 return binding.getPort();
166 }
167 else {
168 return 0;
169 }
170 }
171
172 /***
173 * Gets a string representation of the local IP address that this
174 * socket is bound to, or throws an exception if the socket is not bound.
175 *
176 *@return The local IP address that this socket is bound to
177 *@throws IndyException If the socket is not bound
178 *@see connectClient
179 */
180 public String getBoundIP() throws IndyException {
181 if (binding != null) {
182 return binding.getLocalAddress().getHostAddress();
183 }
184 else {
185 throw new IndyException(IndyUtilities.getResourceString("RSNotBound"));
186 }
187 }
188
189 /***
190 * Gets the local port number that this socket is bound to.
191 *
192 *@return The local port that this socket is bound to.
193 *@throws IndyException if the socket is not bound
194 *@see connectClient
195 */
196 public int getBoundPort() throws IndyException {
197 if (binding != null) {
198 return binding.getLocalPort();
199 }
200 else {
201 throw new IndyException(IndyUtilities.getResourceString("RSNotBound"));
202 }
203 }
204
205 /***
206 * Returns whether this socket is using Nagle's Algortihm.
207 *
208 *@return <code>true</code> if the socket is using Nagle's Algorithm, <code>false</code> otherwise
209 */
210 public boolean getUseNagle() throws IndyIOException {
211 if (isConnected()) {
212 try {
213 return binding.getTcpNoDelay();
214 }
215 catch (SocketException ex) {
216 throw new IndyIOException(ex);
217 }
218 }
219
220 return useNagle;
221 }
222
223 /***
224 * Returns whether or not this instance is connected.
225 *
226 *@return <code>true</code> if the socket is connected.
227 */
228 public boolean isConnected() {
229 if (binding == null) {
230 connected = false;
231 }
232
233 /* if(connected){
234 try {
235 input.mark(1);
236 int b = input.read();
237 if(b==-1){
238 close();
239 }
240 else{
241 input.reset();
242 }
243 }
244 catch (IOException ex) {
245 close();
246 }
247 }*/
248 return connected;
249 }
250
251 /***
252 * Flushes the output buffer of this <code>IOHandlerSocket</code>
253 *
254 *@throws IndyIOException If an IO error occurs whilst flushing
255 *@throws NotConnectedException if the socket is not connected
256 */
257 public void flush() throws IndyIOException {
258 ensureOpen();
259
260 try {
261 output.flush();
262 }
263 catch (IOException ex) {
264 throw new IndyIOException(ex);
265 }
266 }
267
268 /***
269 * Writes a seqeunce of bytes to the socket
270 *
271 *@param b An array of bytes containing the data
272 *@param off The offset at which to start writing
273 *@param len The number of bytes to write
274 *@throws IndyIOException If an IO error occurs
275 *@throws NotConnectedException if the socket is not connected
276 *@throws IndexOutOfBoundsException if there are illegal values of <code>b,off,or len</code>
277 */
278 public void write(byte[] b, int off, int len) throws IndyIOException {
279 ensureOpen();
280
281 try {
282 output.write(b, off, len);
283 }
284 catch (IOException ex) {
285 throw new IndyIOException(ex);
286 }
287 }
288
289 /***
290 * Writes a sequence of bytes to the socket
291 *
292 *@param b The data to write
293 *@throws IndyIOException If an IO error occurs
294 *@see write(byte[],int,int)
295 */
296 public void write(byte[] b) throws IndyIOException {
297 write(b, 0, b.length);
298 }
299
300 /***
301 * Writes a single byte to the socket
302 *
303 *@param b The byte to write
304 *@throws IndyIOException If an IO error occurs
305 */
306 public void write(int b) throws IndyIOException {
307 try {
308 output.write(b);
309 }
310 catch (IOException ex) {
311 throw new IndyIOException(ex);
312 }
313 }
314
315 /***
316 * Reads a single byte of data from the socket
317 *
318 *@return The byte that was read
319 *@throws IndyIOException if an IO error occurs.
320 *@throws PeerDisconnectedException if the remote machine has disconnected
321 *@throws ReadTimedOutException if the read opertaion timed out
322 *@throws NotConnectedException if the socket is not connected
323 */
324 public int read() throws IndyIOException, PeerDisconnectedException,
325 ReadTimedOutException {
326 ensureOpen();
327
328 try {
329 int b = input.read();
330
331 if (b == -1) {
332 close();
333 throw new PeerDisconnectedException(IndyUtilities.getResourceString(
334 "RSConnectionClosedGracefully"));
335 }
336
337 return b;
338 }
339 catch (InterruptedIOException ex) {
340 throw new ReadTimedOutException(IndyUtilities.getResourceString(
341 "RSReadTimedOut"));
342 }
343 catch (IOException ex) {
344 close();
345 throw new IndyIOException(ex);
346 }
347 }
348
349 /***
350 * DOCUMENT ME!
351 *
352 * @param timeout DOCUMENT ME!
353 *
354 * @return DOCUMENT ME!
355 *
356 * @throws IndyIOException DOCUMENT ME!
357 */
358 public int read(int timeout) throws IndyIOException {
359 ensureOpen();
360
361 int oldTime = getReadTimeOut();
362
363 setReadTimeOut(timeout);
364
365 try {
366 return read();
367 }
368 finally {
369 setReadTimeOut(oldTime);
370 }
371 }
372
373 /***
374 * Reads a sequence of bytes from the socket, using the
375 * specified timeout.
376 *
377 *@param b An array of bytes to read the data into
378 *@param off The offset at which to start writing to <code>b</code>
379 *@param len The amount of data to read
380 *@param timeout The timeout to use for reading
381 *@return The number of bytes actually read
382 *@throws IndyIOException If an IO error occurs.
383 *@throws PeerDisconnectedException if the remote machine has disconnected
384 *@throws ReadTimedOutException if the read opertaion timed out
385 *@throws NotConnectedException if the socket is not connected
386 *@throws IndexOutOfBoundsException if b,off, or len are illegal
387 *@throws NullPointerException if b is null
388 *@see read(byte[],int,int)
389 *@see read(byte[],int)
390 *@see read(byte[])
391 *@see read()
392 */
393 public int read(byte[] b, int off, int len, int timeout)
394 throws IndyIOException, ReadTimedOutException {
395 ensureOpen();
396
397 if ((off | len | (off + len) | (b.length - (off + len))) < 0) {
398 throw new IndexOutOfBoundsException();
399 }
400 else if (len == 0) {
401 return 0;
402 }
403
404 if (len == 0) {
405 return 0;
406 }
407
408 if (timeout < 0) {
409 timeout = 0;
410 }
411
412 try {
413 int oldTimeout = binding.getSoTimeout();
414
415 binding.setSoTimeout(timeout);
416
417 try {
418 int nByte = input.read(b, off, len);
419
420 if (nByte == -1) {
421 close();
422 throw new PeerDisconnectedException(IndyUtilities.getResourceString(
423 "RSConnectionClosedGracefully"));
424 }
425
426 return nByte;
427 }
428 catch (InterruptedIOException iioe) {
429 throw new ReadTimedOutException(IndyUtilities.getResourceString(
430 "RSReadTimedOut"));
431 }
432 finally {
433 if (binding != null) {
434 binding.setSoTimeout(oldTimeout);
435 }
436 }
437 }
438 catch (IOException ex) {
439 close();
440 throw new IndyIOException(ex);
441 }
442 }
443
444 /***
445 * Returns the number of bytes that be read from the socket and buffer without blocking
446 *
447 *@return The number of bytes that can be read without blocking
448 *@throws IndyIOException if an IO error occurs
449 */
450 public int available() throws IndyIOException {
451 try {
452 return input.available();
453 }
454 catch (IOException ex) {
455 throw new IndyIOException(ex);
456 }
457 }
458
459 /***
460 * Connects to a remote socket using the parameters given in map.
461 * The map should take the following form:
462 *
463 * <table border="1" cellspacing="3">
464 * <tr>
465 * <th>Key</th><th>Value</th><th>Type</th><th>Required</th>
466 * </tr>
467 * <tr>
468 * <td>"host"</td>
469 * <td>The IP address or FQDN of the remote host to connect to</td>
470 * <td>java.lang.String</td>
471 * <td>Yes</td>
472 * </tr>
473 * <tr>
474 * <td>"port"</td>
475 * <td>The port of the remote host to connect to</td>
476 * <td>java.lang.Stringr</td>
477 * <td>Yes</td>
478 * </tr>
479 * <tr>
480 * <td>"boundip"</td>
481 * <td>The local IP address to bind to</td>
482 * <td>java.lang.String</td>
483 * <td>No</td>
484 * </tr>
485 * <tr>
486 * <td>"boundport"</td>
487 * <td>The local port to bind to</td>
488 * <td>java.lang.String</td>
489 * <td>No</td>
490 * </tr>
491 * </table>
492 *
493 * Key names are case senstive (for now). Sorry.
494 *
495 * @param parameters The parameters to use for connection (see above)
496 * @param timeout The timeout to use for this connection attempt
497 * @throws IndyIOException if an IO error occurs.
498 * @throws IllegalArgumentException if <code>parameters</code> does not contain a required entry (see above)
499 */
500 public void connectClient(Map parameters, int timeout)
501 throws IndyIOException {
502 if (parameters == null) {
503 throw new NullPointerException();
504 }
505
506 String host = null;
507 String boundIP = null;
508 int port = 0;
509 int boundPort = 0;
510
511 host = (String) parameters.get("host");
512 boundIP = (String) parameters.get("boundip");
513 port = Integer.valueOf((String) parameters.get("port")).intValue();
514
515 String boundPortStr = (String) parameters.get("boundport");
516
517 if (boundPortStr != null) {
518 boundPort = Integer.valueOf(boundPortStr).intValue();
519 }
520
521 connectClient(host, port, boundIP, boundPort, timeout);
522 }
523
524 /***
525 * Connects this <code>IOHandlerSocket</code> to a remote socket whose address is given by
526 * <code>host</code> as either an IP address or FQDN and whose port is given by <code>port</code>
527 *
528 * If <code>boundIP</code> or <code>boundPort</code> are not <code>null</code> or < 1 respectively, the socket will bind
529 * to this local address and / or port.
530 *
531 * @param host The remote host to connect to.
532 * @param port The remote port to connect to.
533 * @param boundIP The local address to bind to
534 * @param boundPort The local port to bind to.
535 * @param timeout The timeout to use for this connection attempt
536 * @throws IndyIOException If an IO error occurs.
537 * @throws ConnectException If a connection error occurs, such as the connection being refused by the remote host
538 * @throws ConnectTimedOutException If the connection attempt times out
539 * @throws IndyUnknownHostException If the host can not be resolved.
540 */
541 public void connectClient(String host, int port, String boundIP,
542 int boundPort, int timeout)
543 throws IndyIOException, ConnectException,
544 ConnectTimedOutException, IndyUnknownHostException {
545 //do some bounds checking here
546 if (host == null) {
547 throw new NullPointerException(IndyUtilities.getResourceString(
548 "RSNullHost"));
549 }
550
551 if ((port < 1) || (port > 0xFFFF)) {
552 throw new IllegalArgumentException(IndyUtilities.getResourceString(
553 "RSPortOutOfRange"));
554 }
555
556 if (IndyUtilities.isIP(host)) {
557 doStatus(Status.RESOLVING, new Object[] { host });
558 }
559
560 try {
561 InetAddress local = InetAddress.getByName(boundIP);
562 InetAddress remote = InetAddress.getByName(host);
563
564 doStatus(Status.CONNECTING, null);
565
566 ConnectThread c = new ConnectThread(remote, port, local, boundPort);
567
568 c.start();
569
570 try {
571 c.join(timeout);
572 }
573 catch (InterruptedException ie) {
574 //do nothing, but print a stack trace anyway
575 ie.printStackTrace();
576 }
577
578 if (!c.getConnected()) {
579 //something nuked
580 throw new ConnectException(c.getException());
581 }
582 else {
583 //we may have timed out
584 if (c.getSocket() == null) {
585 //try and interrupt the thread
586 c.interrupt();
587
588 //raise error
589 throw new ConnectTimedOutException(IndyUtilities.getResourceString(
590 "RSConnectTimeout"));
591 }
592 else {
593 //we've connected!
594 binding = c.getSocket();
595
596 try {
597 binding.setKeepAlive(false);
598 input = new MutableBufferedInputStream(binding.getInputStream());
599 output = new BufferedOutputStream(binding.getOutputStream());
600
601 if (readTimeOut > 0) {
602 setReadTimeOut(readTimeOut);
603 }
604 }
605 catch (IOException ex) {
606 ex.printStackTrace();
607 binding = null;
608 throw new IndyIOException(ex);
609 }
610
611 connected = true;
612 doOnConnect();
613 }
614 }
615 }
616 catch (UnknownHostException uhe) {
617 throw new IndyUnknownHostException(uhe);
618 }
619 }
620
621 /***
622 * Closes this socket connection.
623 */
624 public void close() {
625 if (binding != null) {
626 try {
627 binding.getOutputStream().flush();
628
629
630 //binding.shutdownInput();
631 //binding.shutdownOutput();
632 doOnDisconnect();
633 }
634 catch (IOException ioe) {
635 ioe.printStackTrace();
636 }
637 finally {
638 try {
639 connected = false;
640 input.close();
641 output.close();
642 binding.close();
643 }
644 catch (IOException ioe) {
645 ioe.printStackTrace();
646 }
647 finally {
648 input = null;
649 output = null;
650 binding = null;
651 }
652 }
653 }
654 }
655
656 /***
657 * Clears the internal buffer used by this socket
658 */
659 public void clearBuffer() {
660 if (input != null) {
661 input.clear();
662 }
663 }
664
665 /***
666 * Reads a line of data from the socket and assembles it using the given encoding.
667 * If enoding is <code>null</code> the default platform encoding is used.
668 *
669 * @param timeout The timeout to use for this operation
670 * @param maxLineLength The maxiumum line length to accept
671 * @param encoding The character encoding to use to assmble the string
672 * @return A line of data from the socket
673 * @throws IndyIOException if an IO error occurs
674 * @throws PeerDisconnectedException if the remote machine disconnects normally
675 * @throws ReadTimedOutException if the operation times out
676 * @throws MaxLineLengthExceededException if the maximum line length is exceeded before a line break is found
677 * @see readLine(int,int)
678 */
679 public String readLine(int timeout, int maxLineLength, String encoding)
680 throws IndyIOException, PeerDisconnectedException,
681 ReadTimedOutException, MaxLineLengthExceededException {
682 try {
683 ensureOpen();
684 byteBuffer.reset();
685
686 int oldTimeout = binding.getSoTimeout();
687
688 try {
689 timeout_loop:
690 for (long start = System.currentTimeMillis(); timeout > 0;) {
691 binding.setSoTimeout(timeout);
692
693 int b = read();
694
695 switch (b) {
696 //we have a CR - check to see if the next char is a LF
697 case CR:
698 input.mark(1);
699
700 if (input.available() > 0) {
701 int nextByte = input.read();
702
703 if (nextByte != LF) {
704 input.reset();
705 }
706 }
707
708 case LF:
709
710 // we have an LF (or a fall through from CR) , in which case return
711 return (encoding == null)
712 ? new String(byteBuffer.toByteArray())
713 : new String(byteBuffer.toByteArray(), encoding);
714
715 default:
716 byteBuffer.write(b);
717
718 if (byteBuffer.size() > maxLineLength) {
719 throw new MaxLineLengthExceededException(IndyUtilities.getResourceString(
720 "RSMaxLineLengthExceeded"));
721 }
722 }
723
724 timeout -= (System.currentTimeMillis() - start);
725 }
726
727 throw new ReadTimedOutException(IndyUtilities.getResourceString(
728 "RSReadTimedOut"));
729 }
730 finally {
731 if (binding != null) { //we may have closed, so check
732 binding.setSoTimeout(oldTimeout);
733 }
734 }
735 }
736 catch (IOException ex) {
737 close();
738 throw new IndyIOException(ex);
739 }
740 }
741
742 /***
743 * Returns the current data that can be read from the socket without blocking
744 *
745 * @return The data avilable without blocking
746 * @throws IndyIOException If an IO error occurs.
747 * @NotConnectedException if the socket is not connected
748 */
749 public byte[] currentReadBuffer() throws IndyIOException {
750 ensureOpen();
751
752 return input.currentBuffer();
753 }
754
755 private void ensureOpen() throws NotConnectedException {
756 if (binding == null) {
757 connected = false;
758 throw new NotConnectedException(IndyUtilities.getResourceString(
759 "RSNotConnected"));
760 }
761 }
762
763 private boolean testConnected() throws IOException {
764 int oldTimeout = binding.getSoTimeout();
765
766 try {
767 /*** @todo Make this timeout a property? */
768 binding.setSoTimeout(250);
769 input.mark(1);
770
771 try {
772 int b = input.read();
773
774 if (b == -1) {
775 return false;
776 }
777 else {
778 input.reset();
779
780 return true;
781 }
782 }
783 catch (InterruptedIOException iioe) {
784 //timed out, so still connected
785 return true;
786 }
787 }
788 finally {
789 binding.setSoTimeout(oldTimeout);
790 }
791 }
792
793 /***
794 * DOCUMENT ME!
795 *
796 * @param newReadTimeOut DOCUMENT ME!
797 *
798 * @throws IndyIOException DOCUMENT ME!
799 */
800 public void setReadTimeOut(int newReadTimeOut) throws IndyIOException {
801 super.setReadTimeOut(newReadTimeOut);
802
803 if (binding != null) {
804 try {
805 binding.setSoTimeout(newReadTimeOut);
806 }
807 catch (SocketException ex) {
808 throw new IndyIOException(ex);
809 }
810 }
811 }
812
813 /***
814 * DOCUMENT ME!
815 *
816 * @return DOCUMENT ME!
817 *
818 * @throws IndyIOException DOCUMENT ME!
819 */
820 public int getReadTimeOut() throws IndyIOException {
821 if (binding != null) {
822 try {
823 return binding.getSoTimeout();
824 }
825 catch (SocketException ex) {
826 throw new IndyIOException(ex);
827 }
828 }
829 else {
830 return super.getReadTimeOut();
831 }
832 }
833
834 private class MutableBufferedInputStream extends BufferedInputStream {
835 MutableBufferedInputStream(InputStream in) {
836 super(in);
837 }
838
839 public void clear() {
840 count = 0;
841 pos = 0;
842 }
843
844 public byte[] currentBuffer() throws IndyIOException {
845 try {
846 int avail = this.available();
847 byte[] res = new byte[avail];
848
849 if (avail == 0) {
850 if (!testConnected()) {
851 IOHandlerSocket.this.close();
852 throw new PeerDisconnectedException(IndyUtilities.getResourceString(
853 "RSConnectionClosedGracefully"));
854 }
855 }
856
857 int b = this.read(res);
858
859 if (b == -1) {
860 throw new PeerDisconnectedException(IndyUtilities.getResourceString(
861 "RSConnectionClosedGracefully"));
862 }
863
864 return res;
865 }
866 catch (IOException ex) {
867 throw new IndyIOException(ex);
868 }
869 }
870 }
871
872 /***
873 * Thread that performs blocking connect in background.
874 *
875 *@author owen
876 */
877 private class ConnectThread extends Thread {
878 private InetAddress _host;
879 private int _port;
880 private InetAddress _boundIP;
881 private int _boundPort;
882 private IOException exception = null;
883 private Socket sock = null;
884
885 /***
886 * Constructor for the ConnectThread object
887 *
888 *@param host Remote host.
889 *@param port Remote port.
890 *@param boundIP Local IP.
891 *@param boundPort Local port.
892 */
893 public ConnectThread(InetAddress host, int port, InetAddress boundIP,
894 int boundPort) {
895 _host = host;
896 _port = port;
897 _boundIP = boundIP;
898 _boundPort = boundPort;
899 }
900
901 /***
902 * Gets the exception attribute of the ConnectThread object
903 *
904 *@return The exception value
905 */
906 public synchronized IOException getException() {
907 return exception;
908 }
909
910 /***
911 * Gets the connected attribute of the ConnectThread object
912 *
913 *@return The connected value
914 */
915 public synchronized boolean getConnected() {
916 return exception == null;
917 }
918
919 /***
920 * Gets the socket attribute of the ConnectThread object
921 *
922 *@return The socket value
923 */
924 public synchronized Socket getSocket() {
925 return sock;
926 }
927
928 /***
929 * Main processing method for the ConnectThread object
930 */
931 public void run() {
932 try {
933 Socket s = new Socket(this._host, this._port, this._boundIP,
934 this._boundPort);
935
936 if (useNagle) {
937 s.setTcpNoDelay(true);
938 }
939 else {
940 s.setTcpNoDelay(false);
941 }
942
943 sock = s;
944 }
945 catch (IOException ioe) {
946 exception = ioe;
947 }
948 }
949 }
950 }
This page was automatically generated by Maven